/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.demo.query;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.support.DatabaseConnection;
import net.apexes.commons.ormlite.DatabaseHelper;
import net.apexes.commons.ormlite.DatabaseUtil;
import net.apexes.commons.ormlite.Table;
import net.apexes.demo.codegen.enume.support.DemoEnumeSupport;
import net.apexes.demo.codegen.ormlite.column.QAttribute;
import net.apexes.demo.codegen.ormlite.column.QAttributeGroup;
import net.apexes.demo.codegen.ormlite.column.QBrand;
import net.apexes.demo.codegen.ormlite.column.QBusinessDay;
import net.apexes.demo.codegen.ormlite.column.QFeature;
import net.apexes.demo.codegen.ormlite.column.QFeatureGroup;
import net.apexes.demo.codegen.ormlite.column.QGoods;
import net.apexes.demo.codegen.ormlite.column.QGoodsAttribute;
import net.apexes.demo.codegen.ormlite.column.QGoodsBase;
import net.apexes.demo.codegen.ormlite.column.QGoodsComboItem;
import net.apexes.demo.codegen.ormlite.column.QGoodsComboItemGroup;
import net.apexes.demo.codegen.ormlite.column.QGoodsFeature;
import net.apexes.demo.codegen.ormlite.column.QGoodsGroup;
import net.apexes.demo.codegen.ormlite.column.QPay;
import net.apexes.demo.codegen.ormlite.column.QShop;
import net.apexes.demo.codegen.ormlite.column.QShopUser;

import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 */
public class OrmliteDemoDatabaseHelper implements DatabaseHelper {
    
    private static final List<Table<?>> TABLES;
    static {
        List<Table<?>> tables = new ArrayList<Table<?>>();
        tables.add(QAttribute.$);
        tables.add(QAttributeGroup.$);
        tables.add(QBrand.$);
        tables.add(QBusinessDay.$);
        tables.add(QFeature.$);
        tables.add(QFeatureGroup.$);
        tables.add(QGoods.$);
        tables.add(QGoodsAttribute.$);
        tables.add(QGoodsBase.$);
        tables.add(QGoodsComboItem.$);
        tables.add(QGoodsComboItemGroup.$);
        tables.add(QGoodsFeature.$);
        tables.add(QGoodsGroup.$);
        tables.add(QPay.$);
        tables.add(QShop.$);
        tables.add(QShopUser.$);
        TABLES = Collections.unmodifiableList(tables);
        DatabaseHelper.Registry.register(TABLES.toArray(new Table[0]));
        DemoEnumeSupport.getInstance().registerDataPersisters();
    };
    
    private final ConnectionSource connSource;
    
    public OrmliteDemoDatabaseHelper(ConnectionSource connSource) {
        this.connSource = connSource;
    }

    @Override
    public <T, ID> Dao<T, ID> dao(Table<T> table) throws SQLException {
        return DatabaseUtil.dao(connSource, table);
    }

    @Override
    public <E> E callInTransaction(Callable<E> callable) throws Exception {
        DatabaseConnection conn = connSource.getReadWriteConnection(null);
        boolean autoCommitBak = conn.isAutoCommit();
        conn.setAutoCommit(false);
        Savepoint savePoint = null;
        try {
            savePoint = conn.setSavePoint("" + callable);
            E result = callable.call();
            conn.commit(savePoint);
            return result;
        } catch (Exception e) {
            if (savePoint != null) {
                conn.rollback(savePoint);
            }
            throw e;
        } finally {
            conn.setAutoCommit(autoCommitBak);
        }
    }

    @Override
    public void close() {
    }
}
